package classes;

import db.DriverDAO;
import db.ServiceDAO;
import db.VehicleDAO;
import db.VehicleTypeDAO;
import java.util.ArrayList;
import java.sql.Date;
import java.util.List;
import java.sql.Time;
import java.util.Calendar;
import java.util.HashMap;

public class Event {

    private int id;
    private Service service;
    private int serviceID;
    private Driver driver;
    private int driverID;
    private Vehicle vehicle;
    private int vehicleID;
    private String notes;
    private ArrayList<Driver> possibleDrivers;
    private ArrayList<Vehicle> possibleVehicles;
    private Date date;
    private Time servStart;
    private Time servEnd;

    public Event() {
    }

    public Event(int serviceID) {
        this.serviceID = serviceID;

        this.service = ServiceDAO.getServiceByID(serviceID);
        servStart = new Time(service.getStartTime().getTime() - (service.getDriveTime() * 60 * 1000));
        servEnd = new Time(service.getEndTime().getTime() + (service.getDriveTime() * 60 * 1000));
    }

    public Event(int id, int serviceID, int driverID, int vehicleID, String notes, Date date) {
        this.id = id;
        this.serviceID = serviceID;
        this.driverID = driverID;
        this.vehicleID = vehicleID;
        this.notes = notes;
        this.date = date;

        this.service = ServiceDAO.getServiceByID(serviceID);
        this.driver = DriverDAO.getDriverByID(driverID);
        this.vehicle = VehicleDAO.getVehicleByID(vehicleID);

        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.LONG, (int)date.getTime());

        service.setDay(ExtMethods.getDayByNumFull(calendar.get(Calendar.DAY_OF_WEEK)));

        servStart = new Time(service.getStartTime().getTime() - (service.getDriveTime() * 60 * 1000));
        servEnd = new Time(service.getEndTime().getTime() + (service.getDriveTime() * 60 * 1000));
    }

    public int getId() {
        return id;
    }

    public Service getService() {
        return service;
    }

    public void setService(Service service) {
        this.service = service;
    }

    public Driver getDriver() {
        return driver;
    }

    public void setDriver(Driver driver) {
        this.driver = driver;
    }

    public Vehicle getVehicle() {
        return vehicle;
    }

    public void setVehicle(Vehicle vehicle) {
        this.vehicle = vehicle;
    }

    public String getNotes() {
        return notes;
    }

    public void setNotes(String notes) {
        this.notes = notes;
    }

    public int getDriverID() {
        return driverID;
    }

    public void setDriverID(int driverID) {
        this.driverID = driverID;
    }

    public int getServiceID() {
        return serviceID;
    }

    public void setServiceID(int serviceID) {
        this.serviceID = serviceID;
    }

    public int getVehicleID() {
        return vehicleID;
    }

    public void setVehicleID(int vehicleID) {
        this.vehicleID = vehicleID;
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    public List<Driver> getPossibleDrivers() {
        possibleDrivers = new ArrayList<Driver>();
        List<Driver> drivers = DriverDAO.getDrivers();

        for (Driver d : drivers) {

            for (TimeSlot ts : d.getTimeSlots()) {
                if ((ts.getStartTime().before(servStart) || ts.getStartTime().equals(servStart))
                        && (ts.getEndTime().after(servEnd) ||  ts.getEndTime().equals(servEnd))
                        && ts.getWeekDay().equals(getService().getDay())){
                    possibleDrivers.add(d);
                    break;
                }
            }
        }
        return possibleDrivers;
    }

    public List<Driver> getPossibleDrivers(ArrayList<TimeSlot> takenSlots, ArrayList<Driver> drivers) {

        possibleDrivers = new ArrayList<Driver>();
        boolean canDrive = false;
        if (getService().getTransnum() <= 10) {
            for (Driver d : drivers) {

                for (TimeSlot ts : d.getTimeSlots()) {
                    if ((ts.getStartTime().before(servStart) || ts.getStartTime().equals(servStart))
                        && (ts.getEndTime().after(servEnd) ||  ts.getEndTime().equals(servEnd))
                        && ts.getWeekDay().equals(getService().getDay())){

                        canDrive = true;
                        for (TimeSlot takenTS : takenSlots) {

                            if (takenTS.getDriverId() == d.getId()) {

                                boolean startBefServStart;
                                boolean startAftServEnd;
                                boolean endBefServStart;
                                boolean endAftServEnd;


                                startBefServStart = takenTS.getStartTime().before(servStart);
                                startAftServEnd = takenTS.getStartTime().after(servEnd);
                                endBefServStart = takenTS.getEndTime().before(servStart);
                                endAftServEnd = takenTS.getEndTime().after(servEnd);

                                if (!((startBefServStart && endBefServStart)
                                        || (startAftServEnd && endAftServEnd))) {
                                    canDrive = false;
                                    break;
                                }
                            }
                        }
                    }
                    if (canDrive) {
                        possibleDrivers.add(d);
                        break;
                    }
                }
            }
        }
        return possibleDrivers;
    }

    public List<Vehicle> getPossibleVehicles() {

        possibleVehicles = new ArrayList<Vehicle>();
        ArrayList<Vehicle> vehicles = (ArrayList<Vehicle>) VehicleDAO.getVehicles();
        for (Vehicle v : vehicles) {

            if (!v.isBrokenDown()) {

                HashMap<Integer, ArrayList<Time>> vehicleTimes = v.getTimeUsed();

                if (!vehicleTimes.isEmpty()) {
                    ArrayList<Time> vehicleStarts = new ArrayList<Time>();
                    ArrayList<Time> vehicleEnds = new ArrayList<Time>();

                    Time eventStart = getService().getStartTime();
                    Time eventEnd = getService().getEndTime();

                    for (int j = 0; j < vehicleTimes.size(); j++) {
                        vehicleStarts.add(vehicleTimes.get(j).get(0));
                        vehicleEnds.add(vehicleTimes.get(j).get(1));
                    }
                    boolean canDrive = false;

                    boolean startBef;
                    boolean startAft;
                    boolean endBef;
                    boolean endAft;

                    for (int k = 0; k < vehicleTimes.size(); k++) {

                        startBef = vehicleStarts.get(k).before(eventStart);
                        startAft = vehicleStarts.get(k).after(eventStart);
                        endBef = vehicleEnds.get(k).before(eventEnd);
                        endAft = vehicleEnds.get(k).after(eventEnd);

                        if (!((startBef && endBef) || (startAft && endAft)
                                || (startBef && endAft) || (startAft && endBef))) {
                            canDrive = true;
                        }
                        if (canDrive) {
                            possibleVehicles.add(v);
                            break;
                        }
                    }
                } else {
                    possibleVehicles.add(v);
                    break;
                }
            }
        }

        return possibleVehicles;
    }

    public List<Vehicle> getPossibleVehicles(ArrayList<TimeSlot> takenSlots, ArrayList<Vehicle> Vehicles) {

        possibleVehicles = new ArrayList<Vehicle>();
        boolean canDrive = false;
        for (Vehicle v : Vehicles) {
            for (VehicleType vt : VehicleTypeDAO.getVehicleTypes()) {
                if (vt.getNumOfSeats() > service.getTransnum() && !vt.isIgnoreGenerate()) {
                    canDrive = true;
                    if (v.getVehicleTypeID() == vt.getId()) {
                        for (TimeSlot takenTS : takenSlots) {

                            if (takenTS.getDriverId() == v.getId()) {  //Hacked up, DriverID is really VehicleID

                                boolean startBefServStart;
                                boolean startAftServEnd;
                                boolean endBefServStart;
                                boolean endAftServEnd;
                                
                                startBefServStart = takenTS.getStartTime().before(servStart);
                                startAftServEnd = takenTS.getStartTime().after(servEnd);
                                endBefServStart = takenTS.getEndTime().before(servStart);
                                endAftServEnd = takenTS.getEndTime().after(servEnd);

                                if (!((startBefServStart && endBefServStart)
                                        || (startAftServEnd && endAftServEnd))) {
                                    canDrive = false;
                                    break;
                                }
                            }
                        }
                        if (canDrive) {
                            possibleVehicles.add(v);
                            break;
                        }
                    }
                    if (possibleVehicles.size() > 0) {
                        break;
                    }
                }
            }
        }
        return possibleVehicles;
    }
}
